import { DefaultStage } from "../default-stage";
import { MeshBuilder} from '@babylonjs/core/Meshes/meshBuilder'; 
import { RawAssetsUrl } from "../../raw-assets-info";
import { StandardMaterial} from "@babylonjs/core/Materials/standardMaterial";
import { Texture } from "@babylonjs/core/Materials/Textures/texture";
import { ARROW_MODE, HardLineGeometry } from "babylon-lib/geometry/hard-line-geometry";
import { Quaternion, Vector3 } from "@babylonjs/core/Maths/math.vector";
import { HardLineMaterial } from "babylon-lib/material/hard-line-material";
import { Mesh } from "@babylonjs/core/Meshes/mesh";
import { Color3 } from "@babylonjs/core/Maths/math.color";
import { SoftLineGeometry } from "babylon-lib/geometry/soft-line-geometry";
import { SoftLineMaterial } from "babylon-lib/material/soft-line-material";
import { StripsLineGeometry } from "babylon-lib/geometry/strips-line-geometry";
import { StripsLineMaterial } from "babylon-lib/material/strips-line-material";
import { MoveAlongCurvePath } from "babylon-lib/animation/move-along-curve-path";
import { Scene } from "@babylonjs/core/scene";
import { AssetsLoad, TransformNode } from "babylon-lib/index";
import { BasicLineMaterial } from "babylon-lib/material/basic-line-material";
import { BasicLineGeometry } from "babylon-lib/geometry/basic-line-geometry";
import { DetailView } from 'babylon-lib/preset/detail-view';
import { PointingLabel } from 'babylon-lib/preset/pointing-label';
import { CrossImage } from 'babylon-lib/texture/icon-image/cross-image';
import { TickImage } from 'babylon-lib/texture/icon-image/tick-image';
import { ArrowImage } from 'babylon-lib/texture/icon-image/arrow-image';
import { Helper } from 'babylon-lib/tool/helper';
import { WeightedAction } from "babylon-lib/animation/weighted-action";
import { CreateUINode } from 'babylon-lib/gui/base/ui-node';
import { CreateUIButton, UIButton } from 'babylon-lib/gui/control/ui-button';


class InitializeComponent{
    public static initialize(_this:DefaultStage):void{
        const scene=_this.scene;
        const loader=_this.loader(_this.scene);
        this.setBackgroundTexture(_this.canvas,loader);

        // this.testAssets(loader,scene,_this);
        // this.initLines(scene,loader);
        // this.testMACP(scene,loader);
        // this.testGLLine(scene);
        // this.testDetailView(_this);
        // this.testPointingLabel(_this);
        // this.testImage(_this);
        // this.testParams();
        this.testAnimation(_this);
        // this.testGUI(_this);
    }

    private static testGUI(stage:DefaultStage):void{
        let btn:UIButton;
        const node=CreateUINode('dddd',stage.mainScene,{
            lockToCamera:true,
            anchor:new Vector3(0.5,0.5,0),
        },[
            btn=CreateUIButton('hdjsf',stage.mainScene,{
                width:5,
                height:3,
                text:'Abjsjjssj',
                canvasSize:8,
                fontSize:8
            },()=>{
                console.log('click btn');
            })
        ]);

        btn.text='mmkddd';
        setInterval(()=>{
            btn.height-=0.1;
            btn.width-=0.1;
        },1000);

    }

    private static testAnimation(stage:DefaultStage):void{
        const scene=stage.mainScene;
        const loader=stage.loader(scene);

        const nodes=loader.getMeshTaskInfo(RawAssetsUrl.changjing)?.loadedTransformNodes!;
        console.log('nodes',nodes);
        const root=Helper.nodeInArray('model',nodes)!;
        console.log('root',root);
        const container=new TransformNode('testcontainer',stage.mainScene);
        root.parent=container;
        container.scaling.set(0.5,0.5,0.5);
        container.position.set(0,-2,0);

        const animation=loader.getMeshTaskInfo(RawAssetsUrl.changjing)?.loadedAnimationGroups![0]!;
        console.log('animationgroup',animation);
        animation.stop();

        const sa1=new WeightedAction(animation,{from:0,to:25,weight:0,loop:true,speedRatio:0.1});
        const sa2=new WeightedAction(animation,{from:25,to:50,weight:1,loop:true,speedRatio:0.1});

        sa1.start();
        sa2.start();

        let t=0;
        setInterval(()=>{
            t+=0.001;
            t=t%1;
            sa1.weight=t;
            sa2.weight=1-t;
        },30);
        
    }

    private static testParams():void{
        const pf=<T>(ts:T)=>{};
        pf<[number,string]>([1,'s']);
    }

    private static testImage(stage:DefaultStage):void{
        const pn=MeshBuilder.CreatePlane('hhsuduf',{size:2},stage.mainScene);
        const mat=new StandardMaterial('hskdlkfjsd',stage.mainScene);
        pn.material=mat;
        const tex=new Texture(CrossImage(3,'#ffffff'));
        mat.diffuseTexture=tex;
        mat.opacityTexture=tex;
        pn.position.x=-3;

        const pn2=MeshBuilder.CreatePlane('heehsuduf',{size:2},stage.mainScene);
        const mat2=new StandardMaterial('hskdleekfjsd',stage.mainScene);
        pn2.material=mat2;
        const tex2=new Texture(ArrowImage(3,'#ffffff'));
        mat2.diffuseTexture=tex2;
        mat2.opacityTexture=tex2;
        pn2.position.x=0;

        const pn1=MeshBuilder.CreatePlane('heehsuduf',{size:2},stage.mainScene);
        const mat1=new StandardMaterial('hskdleekfjsd',stage.mainScene);
        pn1.material=mat1;
        const tex1=new Texture(TickImage(3,'#ffffff'));
        mat1.diffuseTexture=tex1;
        mat1.opacityTexture=tex1;
        pn1.position.x=3;
    }

    private static testPointingLabel(stage:DefaultStage):void{
        const m=MeshBuilder.CreateBox('bbsodj',{width:3,height:0.1,depth:0.5},stage.mainScene);

        const pl=new PointingLabel('bbb',{
            text:'bug测试',
            pointRadius:0.04,
            autoUpdatePointLineStart:true,
            background:'#00ff00',
            fontSize:26
        },stage.mainScene);
        pl.points=[new Vector3(-2,-2,-2)];
        pl.position=new Vector3(4,2,1);
        pl.rotationQuaternion=Quaternion.FromEulerAngles(0,1.57,0);

        pl.parent=m;
        setInterval(()=>{
            m.rotation.y+=0.01;
        },50);
    }

    private static testDetailView(stage:DefaultStage):void{
        const scene=stage.scene;
        const box=MeshBuilder.CreateBox('tbox',{width:5,height:2,depth:3},scene);
        box.position.set(0,0,3);
        const node=new TransformNode('coantainer',scene);
        box.parent=node;

        const dv=new DetailView('detailView',scene,stage.targetScene,{
            size:1.5,
            billboard:Mesh.BILLBOARDMODE_ALL,
            hasAlpha:true,
        });
        dv.body.position=new Vector3(0,3,0);

        const box1=MeshBuilder.CreateBox('targetBox',{width:4,height:2,depth:3},stage.targetScene);
        box1.position=new Vector3(0,0,0);
        const material=new StandardMaterial('target-box-material',stage.targetScene);
        material.disableLighting=true;
        material.emissiveColor=new Color3(1,0,0);
        box1.material=material;
        dv.addRenderTarget(box1);

        stage.actor.detailView=dv;

        setInterval(()=>{
            box.rotation.y+=0.01;
            box1.rotation.x+=0.01;
            box1.rotation.z+=0.01;
        },50);
    }

    private static setBackgroundTexture(canvas:HTMLCanvasElement,loader:AssetsLoad):void{
        const backTex=loader.getTextureTaskInfo(RawAssetsUrl.background)?.texture!;
        canvas.style.backgroundImage='url('+backTex.url+')';
        canvas.style.backgroundSize='cover';        
    }

    private static testGLLine(scene:Scene):void{
        const ps=[
            new Vector3(Math.random()*4-2,Math.random()*4-2,Math.random()*4-2),
            new Vector3( Math.random()*4-2,Math.random()*4-2,Math.random()*4-2),
            new Vector3( Math.random()*4-2,Math.random()*4-2,Math.random()*4-2),
            new Vector3( Math.random()*4-2,Math.random()*4-2,Math.random()*4-2),
        ];
        const g=new BasicLineGeometry('dfsd',ps,{
            autoUpdateDistances:true,
        },scene);
    
        const m=new Mesh('asdfs',scene);
        // const m=new LinesMesh('sdfsdfs',scene);
        g.applyToMesh(m);
        m.material=new BasicLineMaterial('ffd',scene,{
            color:new Color3(0,1,0),
            dashed:true,
        });
        // const mat=new StandardMaterial('ddd',scene);
        // mat.fillMode=Material.LineListDrawMode;
        // m.material=mat;

        setInterval(()=>{
            if(ps.length>10000)return;
            ps.push(new Vector3(Math.random()*4-2,Math.random()*4-2,Math.random()*4-2));
            g.vertices=ps;
        },100);
    }

    private static testMACP(scene:Scene,loader:AssetsLoad):void{
        const ps=[];
        const c=50;
        const u=Math.PI*2/c;
        const r=3;
        for(let i=0;i<c;i++){
            ps.push(new Vector3(
                Math.sin(i*u)*r,
                Math.cos(i*u)*r,
                0
            ));
        }
        const macp=new MoveAlongCurvePath(scene,ps,{
            closed:true,
            reciprocal:false
        });
        const cc=10;
        for(let i =0;i<cc;i++){
            const s=MeshBuilder.CreateBox('sph'+i,{width:0.4,height:0.1,depth:0.2},scene);
            macp.addTarget(s,0.1,Math.random()-0.5,Math.random()-0.5);
            macp.stepIn(Math.random()*3);
        }
        macp.debug={color:new Color3(0,1,0)};
        setInterval(()=>{
            macp.stepIn(0.05);
        },50);
    }
    private static testAssets(loader:AssetsLoad,scene:Scene,stage:DefaultStage):void{

        const movie=loader.getVideoTextureTaskInfo(RawAssetsUrl.movie)?.texture!;
        const video=loader.getVideoTextureTaskInfo(RawAssetsUrl.video)?.texture!;

        const sound=loader.getAudioTaskInfo(RawAssetsUrl.music)?.sound!;
        sound.loop=true;

        const cubeTexture=loader.getHDRCubeTextureTaskInfo(RawAssetsUrl.hdrCube)!.texture!;
        // const cubeTexture=loader.getEquiRectangularCubeTextureTaskInfo(RawAssetsUrl.erCube)!.texture!;
        // const cubeTexture=loader.getCubeTextureTaskInfo(RawAssetsUrl.lightCubePX)!.texture!;
        cubeTexture.invertZ=true;

        const skyBox=MeshBuilder.CreateBox('box',{size:1},scene);
        const skyMat=new StandardMaterial('sky',scene);
        skyMat.backFaceCulling=false;
        skyMat.reflectionTexture=cubeTexture;
        skyMat.reflectionTexture.coordinatesMode=Texture.SKYBOX_MODE;
        skyMat.disableLighting=true;
        skyBox.material=skyMat;
        skyBox.position.z=4;

        const screen=MeshBuilder.CreatePlane('screen',{width:1,height:0.6},scene);
        const screenMat=new StandardMaterial('screen-mat',scene);
        screenMat.diffuseTexture=movie;
        screenMat.backFaceCulling=false;
        screen.material=screenMat;
        screen.position.x=4;

        const screen1=MeshBuilder.CreatePlane('screen',{width:1,height:0.6},scene);
        const screenMat1=new StandardMaterial('screen-mat1',scene);
        screenMat1.diffuseTexture=video;
        screenMat1.backFaceCulling=false;
        screen1.material=screenMat1;
        screen1.position.x=-4;

        stage.onUserGestureObservable.add((debut)=>{
            if(!debut)return;
            sound.play();
            movie.video.play();
            video.video.play();
        });
    }
    private static initLines(scene:Scene,loader:AssetsLoad):void{
        let points=[
            new Vector3(-6,-2,0),
            new Vector3(0,2,0),
            new Vector3(4,-2,0),
            new Vector3(6,2,0),
        ];
        const tex1=loader.getTextureTaskInfo(RawAssetsUrl.buttonClasses)?.texture!;
        const geo=new HardLineGeometry('tl',points,{
            arrowMode:ARROW_MODE.DOUBLE
        },scene);
        const mat=new HardLineMaterial('tlm',scene,{
            diffuseTexture:tex1,
            diffuseColor:new Color3(1,0.5,0.2)
        });
        const line=new Mesh('ll',scene);
        geo.applyToMesh(line);
        line.material=mat;
        mat.bind(line.getWorldMatrix());
        
        points=[
            new Vector3(-6,2,-2),
            new Vector3(0,-2,-2),
            new Vector3(4,2,-2),
            new Vector3(6,-2,-2)
        ];
        const geo1=new SoftLineGeometry('tll',points,{},scene);
        const mat1=new SoftLineMaterial('tllm',scene,{
            diffuseTexture:tex1,
            diffuseColor:new Color3(0,1,0)
        });
        const line1=new Mesh('lll',scene);
        geo1.applyToMesh(line1);
        line1.material=mat1;
        mat1.bind(line1.getWorldMatrix());

        points=[
            new Vector3(-4,-2,1),new Vector3(4,-2,1),
            new Vector3(-4,0,1),new Vector3(4,0,1),
            new Vector3(-4,2,1),new Vector3(4,2,1)
        ];
        const geo2=new StripsLineGeometry('ttl',points,{},scene);
        const mat2=new StripsLineMaterial('hsj',scene,{
            diffuseTexture:tex1,
            diffuseColor:new Color3(1,1,0)
        });
        mat2.backFaceCulling=false;
        const line2=new Mesh('l22',scene);
        geo2.applyToMesh(line2);
        line2.material=mat2;
        mat2.bind(line2.getWorldMatrix());
        geo2.updateDistance();

        setInterval(()=>{
            if(points.length>100)return;
            points.push(new Vector3(Math.random()*10-5,Math.random()*10-5,Math.random()*10-5));
            geo2.vertices=points;
        },5000);
    }
    
}

export {InitializeComponent};
